#include "header.h"
#include "cmdline.h"


unsigned char *msg;

//typedef struct param{
	//int test;
//};

char *format;
char *_output_device;
u_short portnum;

int _number_of_sample_receive;

int _nber_of_packet_per_s;
int _nb_paquets_emis;

//previous value of packets receive
int _old_value;

void *thread_code(void *vargp);

double avg_mean_lost;
double mean_throughput;


int _cpt;

int end_flag;

main(int argc, char **argv)
{

  int fd;	/* sound device file descriptor */
  int arg;	/* argument for ioctl calls */
  int status;   /* return status of system calls */
  
  pthread_t thread_list;
  
  _number_of_sample_receive = 0;
  
  _nber_of_packet_per_s = 0;
  
  avg_mean_lost = 0;
  
  mean_throughput = 0;
  
  _old_value = 0;
  
  end_flag = 0;
  
  _cpt = 0;
  
  size_t cc, addr_in_size;
  msg = (unsigned char*)malloc(sizeof(unsigned char)*TAILLE);
  int sockfd;
  portnum = SERV_PORT;
  struct sockaddr_in *my_addr, *from;
  
  u_long fromaddr;

  addr_in_size = sizeof(struct sockaddr_in);
  
  
  _output_device = (char*)malloc(sizeof(char)*MAX_INPUT_SIZE);
  format = (char*)malloc(sizeof(char)*MAX_INPUT_SIZE);
    //set the default format to be mu-law
  	//strncpy(format,MU_LAW_FILE,strlen(MU_LAW_FILE));
  	strcpy(_output_device,MU_LAW_FILE);
  	strcpy(format,MU_LAW);
  
  _parse(argc,argv,&portnum,format);
  
  //printf("=%s=",format);
  
  //set the conveniant parameters before opening sound device
  if(strcmp(format,PCM) == 0){
  	
  	strcpy(_output_device,PCM_FILE);
  	printf("Output audio device : %s \n",_output_device);
  	fd = open_audio_device_PCM(_output_device,O_WRONLY); 
  }
  else{
    printf("Output audio device : %s \n",_output_device);
  	fd = open_audio_device_MuLaw(_output_device,O_WRONLY);
  	
  }
  
  
  from = (struct sockaddr_in *)malloc(addr_in_size);
  my_addr = (struct sockaddr_in *)malloc(addr_in_size);

  memset((char *)my_addr,(char)0,addr_in_size);
  my_addr->sin_family = AF_INET;
  my_addr->sin_addr.s_addr = htonl(INADDR_ANY);
  my_addr->sin_port = portnum;

  if((sockfd = socket (PF_INET, SOCK_DGRAM, 0)) < 0){
   // fprintf(stderr,"Error %d in socket: %s\n",errno,sys_errlist[errno]);
    exit(0);
  };

  if(bind(sockfd, (struct sockaddr *)my_addr, addr_in_size) < 0){
  	err_stop("unable to bind the address "); 
  };
  
 
  
  //thread realisant le calcul des statistiques
  
  pthread_create(&thread_list, NULL,thread_code,NULL);
  
  char *send_buff = (char*)malloc(sizeof(char)*15);
   
  //fprintf(stdout,"Ready to receive\n");
  
 	char*p = (char*)malloc (sizeof(char)*TAILLE*2);  

  while(recvfrom (sockfd,p,TAILLE*2,0,(struct sockaddr *)from,&addr_in_size)){
   // if((cc = recvfrom (sockfd,p,TAILLE*2,0,(struct sockaddr *)from,&addr_in_size)) == -1){
    //  		err_stop("Unable to receive data");
   // };
  	end_flag = 1;
    char nombre[10];
    int r=0;
    while(p[r]!='$'&& r < 10){
    	nombre[r] = p[r];
    	r++;
    }
    
    msg = p+r+1;
    
   // int * st = memcpy(&_nb_paquets_emis,p,sizeof(_nb_paquets_emis));
   // char * mg = memcpy(msg,p + sizeof(_nb_paquets_emis),TAILLE);
    //memcpy(p,&_nber_of_samples_send,sizeof(_nber_of_samples_send));
  	//memcpy(p + sizeof(_nber_of_samples_send),msg,sizeof(msg));
  	
  
    
   fromaddr = from->sin_addr.s_addr;
   _nb_paquets_emis = atoi(nombre);
  // printf("nombre  %d \n",atoi(nombre));
   
    write(fd,msg,strlen(msg));
    _number_of_sample_receive++;
  }
}

void *thread_code(void *vargp)
{ 
	int debit = 0;
	double taux_perte=0;
	
	char* format_string = "%15d %30d %40f\n";
	printf("\n");
	printf("*********************************************************\n");
	printf("*                                                       *\n");
	printf("*             Statistiques instantanees                 *\n");
	printf("*                                                       *\n");
	printf("* Le taux de perte calcule apres chaque seconde      *\n");
	printf("*********************************************************\n");
	
	printf("  \n");
	fprintf(stdout,"%8s %13s %20s %30s \n","Echantion recus","Debit Moyen reception","Taux de pertes","Sent sample");
	
	//printf("Echantionn recus\t Debit Moyen reception \t Taux de pertes \n");
	
	while(1)
	{   
		//le thread va dormir une seconde et se reveille pour 
		//calculer les statistiques
		sleep (1);
		//compute the throughput in Kbps
		debit = ((_number_of_sample_receive - _old_value)*8*160)/1000;
		if(_nb_paquets_emis != 0){
			taux_perte = (double)((_nb_paquets_emis+1) - _number_of_sample_receive)/_nb_paquets_emis;
		}
		if(taux_perte < 0)
			taux_perte = -1*taux_perte;
			
		if(end_flag == 1 && debit != 0)
			_cpt++;	
		
		avg_mean_lost += taux_perte;
  
  		mean_throughput += debit;
		
		//printf(format_string, _number_of_sample_receive, debit,taux_perte);
		_old_value = _number_of_sample_receive;
		fprintf(stdout,"%8d %15d Kbps %25lf %30d \n",_number_of_sample_receive,debit,taux_perte,_nb_paquets_emis);
		if((end_flag == 1) && (debit == 0)){
			
			printf(" \n ");
			fprintf(stdout,"%s \n", "***************************Statistiques globales **************************");
			printf(" Debit Moyen de transmission : %lf Kbps \n", (double)(mean_throughput/_cpt));
			printf(" Taux moyen de pertes : %lf \n", (double)(avg_mean_lost/_cpt));
			printf(" Nombre Total d'echqntions recu : %d \n",_number_of_sample_receive);
			printf(" Estimation du nombre d'echantillons emis : %d \n",_nb_paquets_emis + 1 );
			fprintf(stdout,"%s \n", "***************************Statistiques globales **************************");
			printf(" \n ");
			//exit(0);
		}
			
		
		
		
	}
}





